<?php
declare (strict_types = 1);

namespace app\service\logic\common\finance;

use app\exception\LogicException;
use app\facade\StringFacade;
use app\facade\WechatpayFacade;
use app\model\communal\FinanceCoinModel;
use app\model\communal\UserWechatOpenModel;
use app\service\logic\BaseService;
use app\service\logic\common\user\StatisticsService;
use app\service\logic\common\user\UserWechatOpenService;
use Carbon\Carbon;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\Model;

final class FinanceCoinService extends BaseService
{
    protected string $modelClassName = 'FinanceCoinModel';

    /**
     * 提现操作
     *
     * @param $params
     * @return FinanceCoinModel|Model
     * @throws LogicException
     */
    public function cashOperate($params)
    {
        $isBind = invoke(UserWechatOpenService::class)->isBindByUserId($params['user_id']);
        if (2 == $isBind['is_bind']) {
            throw new LogicException('请先绑定微信');
        }


        $coinCount = $params['coin_count'];
        if ($coinCount < 500) {
            throw new LogicException('满500元心币可以提现');
        }
        // 可用元心币
        $availableCoin = invoke(StatisticsService::class)->getCoinAvailableCountByUserId($params['user_id']);
        if ($coinCount > $availableCoin) {
            throw new LogicException('可用元心币不足');
        }

        Db::connect('communal')->transaction(function () use ($params, $coinCount, &$model) {
            // 锁定提现的元心币  提现成功再解锁
            invoke(StatisticsService::class)->freezeCoin($params['user_id'], $coinCount);

            $amount = StringFacade::coinToAmount($coinCount);
            $params['amount'] = $amount;
            $model = FinanceCoinModel::create($params);
            $number = StringFacade::createStringById($model['id'], 'FC', 16);
            $model->save(['number' => $number]);
        });
        return $model;
    }

    /**
     * get type map
     *
     * @param $type
     * @return string
     */
    public function getTypeMap($type)
    {
        // 订单状态 1 待审核 2 审核驳回 3 审核通过 4 提现成功
        $payment = [1 => '待审核', 2 => '审核驳回', 3 => '审核通过', 4 => '提现成功'];
        return $payment[$type] ?? '其他';
    }

    /**
     * 审核
     *
     * @param $params
     * @return array|mixed|Model
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function rr($params)
    {
        $model = $this->getSimpleDetail($params);

        Db::connect('communal')->transaction(function () use ($params, &$model) {
            $type = $params['type'];
            if (2 == $type) {
                // 审核驳回
                $model->save($params);
                // 返还锁定元心币
                invoke(StatisticsService::class)->unfreezeCoin($model['user_id'], $model['coin_count']);
            } elseif (3 == $type) {
                // 获取绑定微信
                $wechat = UserWechatOpenModel::findOrFail($model['user_id']);
                // 审核通过
                if (empty($model['number_md5'])) {
                    // 订单首次支付
                    // 支付订单md5编号
                    $numberMd5 = md5($model['number'] . Carbon::now());
                    $model->save(['number_md5' => $numberMd5]);
                } else {
                    $numberMd5 = $model['number_md5'];
                }
                $model->save($params);
                // 调个微信接口
                WechatpayFacade::v3TransferBatches(                [
                    'out_batch_no' => $numberMd5,
                    'total_amount' => $model['amount'],
                    'total_num' => 1,
                    'transfer_detail_list' => [
                        [
                            'out_detail_no' => $numberMd5,
                            'transfer_amount' => $model['amount'] * 100,
                            'transfer_remark' => '元心币提现',
                            // 根据用户绑定微信获取openid
                            'openid' => $wechat['openid'],
                        ]
                    ],
                ]);

                // 微信响应成功
                // 消耗元心币
                invoke(StatisticsService::class)->consumeFreezeCoin($model['user_id'], $model['coin_count'], 3);
            }
        });

        return $model;
    }
}
